/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_ui.htm
 *
 * Zhiqim UI is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
 
+(function(Z)
{//BEGIN

Z.Input = Z.Class.newInstance();
//定义支持的类型数值的,整数,小数的,字母的,两位小数金额的,折扣值,小时分钟值
Z.Input.types = ["Numeric", "Alphabetic", "AlphaNumeric", "Integer", "Decimal", "Amount2R", "Discount", "Date", "HourMinute"];
Z.Input.speTypes = ["number", "email"];
Z.Input.prototype = 
{
    defaults:
    {
        elem: null,
        options: null
    },
    
    init: function()
    {//初始化
        if (!this.elem)
            return;
            
        this.$elem = Z(this.elem);
        
        if (!this.options && !Z.AR.contains(Z.Input.speTypes, this.$elem.attr("type")))
            return;
        
        // max（最大值）/maxlength（最大长度） 特殊处理
        if (this.$elem.attr("max") != null)
        {
            this.$elem.max = parseFloat(this.$elem.attr("max"));
        }
        if (this.$elem.attr("maxlength") != null)
        {
            this.$elem.maxlength = parseInt(this.$elem.attr("maxlength"));
        }
        
        //键点击双击,按下事件,按下恢复事件和值被修改事件
        this.$elem.on("input",this.onInput, this);
    },
    
    /************************************************/
    //事件方法，设置三种控制方式：
    //1、键按下时判断是否可以输入，用is开头方法
    //2、键恢复时表示判断通过，用on再检查一次
    //3、由其他方式修改了值input事件时，用ch检查控制
    //4、由设置值方式修改值，不会触发input方法暂时没办法控制
    /************************************************/
    
    onInput: function(e)
    {
        this.call("on", e);
    },
    call: function(action, e)
    {
        if (!this.options)
        {
            this.$elem.val(this.inputMax(this.$elem.val()));
        }
        else if (this.options.type && action+this.options.type in this)
        {
            this[action+this.options.type].call(this, e);
        }
    },
    inputMax: function(value)
    {
        if (this.$elem.max && +value > this.$elem.max)
            return value = this.$elem.max;
        if (this.$elem.maxlength && (""+value).length > this.$elem.maxlength)
            return value = value.substring(0,this.$elem.maxlength);
        return value;
    },
    
    /************************************************/
    //数值型判断,替换和粘贴
    /************************************************/
    onNumeric: function(e)
    {//处理非数值型数据
        var value = this.$elem.val();
        if (!/^[0-9]*$/.test(value))
        {
            value = value.replace(/[^0-9]/g, "");
            this.inputMax(value);
            this.$elem.val(value);
        }
    },

    /************************************************/
    //整数型判断,替换和粘贴
    /************************************************/
    onInteger: function(e)
    {//处理非整数型数据
        var value = this.$elem.val();
        if (!/^[0-9]*$/.test(value)){
            value = value.replace(/[^0-9]/g, "");
        }
        
        value = Z.S.prefixZeroRemove(value);
        this.inputMax(value);
        this.$elem.val(value);
    },
    
    /************************************************/
    //小数型判断,替换和粘贴
    /************************************************/
    onDecimal: function(e)
    {//处理非小数型数据
        var value = this.$elem.val();
        if (!/^[0-9.]*$/.test(value)){
            value = value.replace(/[^0-9.]/g, "");
        }
        
        //删除前缀0，第二个点后数据，如果首符是.则加为0.
        value = Z.S.prefixZeroRemove(value);
        value = Z.S.removeSecondDot(value);
        if (value.length > 0 && value.charAt(0) == '.'){
            value = "0" + value;
        }
            
        this.inputMax(value);
        this.$elem.val(value);
    },
    
    /************************************************/
    //字母型判断,替换和粘贴
    /************************************************/
    onAlphabetic: function(e)
    {//处理非字母型数据
        var value = this.$elem.val();
        if (!/^[a-zA-Z]*$/.test(value))
        {
            value = value.replace(/[^a-zA-Z]/g, "");
            this.$elem.val(value);
        }
    },
    
    /************************************************/
    //字母数值型判断,替换和粘贴
    /************************************************/
    onAlphabeticNumeric: function(e)
    {//处理非字母型数据
        var value = this.$elem.val();
        if (!/^[0-9a-zA-Z]*$/.test(value))
        {
            value = value.replace(/[^0-9a-zA-Z]/g, "");
            this.$elem.val(value);
        }
    },
    
    /************************************************/
    //2位小数的金额判断,替换和粘贴
    /************************************************/
    onAmount2R: function(e)
    {
        var value = this.$elem.val();
        if (!/^[0-9.]*$/.test(value)){
            value = value.replace(/[^0-9.]/g, "");
        }
        
        //删除前缀0，第二个点后数据，如果首符是.则加为0.
        value = Z.S.prefixZeroRemove(value);
        value = Z.S.removeSecondDot(value);
        if (value.length > 0 && value.charAt(0) == '.'){
            value = "0" + value;
        }
        
        //金额还要增加2位小数限制
        var ind = value.indexOf(".");
        if (ind != -1 && ind <= value.length-1-2){
            value = value.substring(0, ind+1+2);
        }
        this.inputMax(value);
        this.$elem.val(value);
    },
    
    /************************************************/
    //折扣(0.01-10)判断,替换和粘贴
    /************************************************/
    onDiscount: function(e)
    {
        var value = this.$elem.val();
        if (!/^[0-9.]*$/.test(value)){
            value = value.replace(/[^0-9.]/g, "");
        }
            
        //删除前缀0，第二个点后数据，如果首符是.则加为0.
        value = Z.S.prefixZeroRemove(value);
        value = Z.S.removeSecondDot(value);
        if (value.length > 0 && value.charAt(0) == '.'){
            value = "0" + value;
        }
        
        //折扣还要增加2位小数限制
        var ind = value.indexOf(".");
        if (ind != -1 && ind <= value.length-1-2){
            value = value.substring(0, ind+1+2);
        }
        
        //再比较不允许大于10,大于10则置空
        this.$elem.val((parseFloat(value) > 10)?"":value);
    },
    
    /************************************************/
    //日期(yyyy-MM-dd)判断,替换和粘贴
    /************************************************/
    onDate: function(e)
    {
        var value = this.$elem.val();
        if (!/^[0-9\-]*$/.test(value))
            value = value.replace(/[^0-9\-]/g, "");
            
        //再比较是否有效，有效则加入，否则置空
        var regexp = null;
        switch(value.length)
        {
            case 1:regexp = /^[0-9]$/;break;
            case 2:regexp = /^[0-9]{2}$/;break;
            case 3:regexp = /^[0-9]{3}$/;break;
            case 4:regexp = /^[0-9]{4}$/;break;
            case 5:regexp = /^[0-9]{4}\-$/;break;
            case 6:regexp = /^[0-9]{4}\-[0-1]$/;break;
            case 7:regexp = /^[0-9]{4}\-(0[1-9]|1[0-2])$/;break;
            case 8:regexp = /^[0-9]{4}\-(0[1-9]|1[0-2])\-$/;break;
            case 9:regexp = /^[0-9]{4}\-(0[1-9]|1[0-2])\-[0-3]$/;break;
            case 10:regexp = Z.R.DATE;break;
        }
        
        //再比较是否有效，有效则加入，否则置空
        this.$elem.val((!regexp || !regexp.test(value))?"":value);
    },
    
    /************************************************/
    //小时分钟(00:00)判断,替换和粘贴
    /************************************************/
    onHourMinute: function(e)
    {
        var value = this.$elem.val();
        if (!/^[0-9:]*$/.test(value))
            value = value.replace(/[^0-9:]/g, "");
            
        //再比较是否有效，有效则加入，否则置空
        var regexp = null;
        switch(value.length)
        {
            case 1:regexp = /^[0-2]$/;break;
            case 2:regexp = /^([0-1][0-9]|[2][0-3])$/;break;
            case 3:regexp = /^([0-1][0-9]|[2][0-3]):$/;break;
            case 4:regexp = /^([0-1][0-9]|[2][0-3]):([0-5])$/;break;
            case 5:regexp = /^([0-1][0-9]|[2][0-3]):([0-5][0-9])$/;break;
        }
        
        //再比较是否有效，有效则加入，否则置空
        this.$elem.val((!regexp || !regexp.test(value))?"":value);
    }
}

Z.Input.load = function(target)
{//加载函数
    //如果传入了目标，则在目标中查找，否则查找全部
    Z.$selector("input", target).each(function(elem)
    {
        if (Z.B.msie)
        {//IE处理成灰色和主流一致
            Z.placeholder(elem);
        }
        
        if (Z.EL.get(elem, "readonly") != null)
        {//如果有只读属性时不响应回退等按键,注意element里有readonly属性,默认=null
            Z.E.add(elem, "keydown", Z.E.forbidden);
            return;
        }
        
        if (!Z.EL.has(elem, "data-options"))
        {
            //email、number 特殊处理
            var inputType = Z.EL.get(elem, "type");
            if (Z.AR.contains(Z.Input.speTypes, inputType))
            {
                if (Z.EL.get(elem, "max") != null || Z.EL.get(elem, "maxlength") != null)
                    return new Z.Input({elem: elem});
            }
            return;
        }
        
        //解析表达式并放置到哈唏表中
        var expression = Z.EL.get(elem, "data-options");
        var options = Z.AR.toObject(expression, ";");
        if (!options.type || !Z.AR.contains(Z.Input.types, options.type))
        {//不支持的类型不处理
            return;
        }
        
        //关闭输入法,chrome不支持,ie和firefox支持
        Z.EL.addClass(elem, "z-ime-disabled");
        new Z.Input({elem: elem, options: options});
    });
};

Z.onload(Z.Input.load);

/****************************************/
//“数量修改输入框”
/****************************************/
Z.NumInput = {};
Z.NumInput.load = function(target)
{
    Z.$selector("[data-role=z-numInput]", target).each(function(elem)
    {//遍历目标范围内
        var $minus = Z(elem).find(".z-btn-minus");
        var $plus = Z(elem).find(".z-btn-plus");
        var $input = Z(elem).find("input[type=text]");
        if (!$minus[0] || !$plus[0] || !$input[0]){
            return false;
        };
        $input.off("input",Z.NumInput.numInput).on("input",Z.NumInput.numInput);
        $plus.off("touchend",Z.NumInput.numPlus).on("touchend",Z.NumInput.numPlus);
        $minus.off("touchend",Z.NumInput.numMinus).on("touchend",Z.NumInput.numMinus);
    });
}

Z.NumInput.numInput = function(ev)
{//输入框 input 事件
    var $input = Z(this);
    var val = $input.val();
    var min = parseInt($input.attr("data-min")) || 1;
    val = val.replace(/[^\d]/g,"");
    while (val.charAt(0) == "0" && val.length > 1){
        val = val.substring(1);
    }
    if (val == ""){
        val = min;
    }
    $input.val(val);
}

Z.NumInput.numPlus = function(ev)
{//数值累加
    Z.E.forbidden(ev);
    var $plus = Z(this);
    var $input = $plus.parent().find("input[type=text]");
    var val = parseInt($input.val());
    val++;
    $input.val(val);
}

Z.NumInput.numMinus = function(ev)
{//数值递减
    Z.E.forbidden(ev);
    var $minus = Z(this);
    var $input = $minus.parent().find("input[type=text]");
    var min = parseInt($input.attr("data-min")) || 1;
    var val = parseInt($input.val());
    val--;
    val = (val < min)?min:val;
    $input.val(val);
}

/******************************************************/
//支持form使用iframe调用
/******************************************************/
Z.CallFrame = {};
Z.CallFrame.load = function()
{
    Z("form[data-role=z-call-frame]").each(function(form)
    {
        //1.先判断是否存在<iframe name="zCallFrame"></iframe>
        var $frame = Z('iframe[name="zCallFrame"]');
        if ($frame.length == 0)
            $frame = Z('<iframe name="zCallFrame" style="display:none;"></iframe>').prependTo("body");
            
        //2.设置form的target
        form.target = "zCallFrame";
        
        //3.设置zFormIndex
        if (!form.zFormIndex)
        {
            var zFormIndex = document.createElement("input");
            zFormIndex.name = "zFormIndex";
            zFormIndex.type = "hidden";
            form.insertBefore(zFormIndex, form.firstNode);
        }
        var ind = -1;
        for (var i=0;i<document.forms.length;i++)
        {
            if (form == document.forms[i])
            {
                ind = i;
                break;
            }
        }
        form.zFormIndex.value = ind;
        
        //4.设置zCallFrame
        if (!form.zCallFrame)
        {
            var zCallFrame = document.createElement("input");
            zCallFrame.name = "zCallFrame";
            zCallFrame.type = "hidden";
            form.insertBefore(zCallFrame, form.firstNode);
        }
        form.zCallFrame.value = "true";
    });
};

Z.onload(Z.CallFrame.load);

/*************************************************************************************/
//描述对象
/*************************************************************************************/
Z.placeholder = function(elem)
{
    var $elem = Z.$elem(elem);
    var ph = $elem.attr("placeholder");
    if (Z.V.isEmptyBlank(ph))
        return;
    
    $elem.removeAttr("placeholder");
    var width = $elem.offsetWidth();
    var height = $elem.offsetHeight();

    //创建一个封套把input/textarea和placeholder包含在一起
    var $cover = Z.$cover($elem);
    
    //创建描述对象
    var $placeholder = Z('<div class="z-placeholder">'+ph+'</div>');
    $placeholder.appendTo($cover)
                .opacity(0.8)
                .css({width: width, height: height})
                .cssMaybe("padding-left", $elem.cssNum("paddingLeft")+2)//保留光标2像素位置
                .cssMaybe("padding-right", $elem.css("paddingRight"))
                .cssMaybe("padding-top", $elem.css("paddingTop"))
                .cssMaybe("padding-bottom", $elem.css("paddingBottom"))
                .cssMaybe("font-family", $elem.css("fontFamily"))
                .cssMaybe("font-size", $elem.css("fontSize"))
                .cssMaybe("line-height", $elem.css("lineHeight"))
                .cssMaybe("text-indent", $elem.css("textIndent"));
                
    if ($elem.val().length > 0){
        $placeholder.hide();
    }

    //事件隐藏和显示描述
    $elem.keydown(function(){$placeholder.hide();});
    $elem.keyup(function()
    {
        if ($elem.val().length > 0)
            $placeholder.hide();
        else
            $placeholder.show();
    });
}

/*************************************************************************************/
//<pre>对象
/*************************************************************************************/
Z.preRemoveBR = function()
{//定义了.z-text-prewrap和.z-text-preline样式且不是pre标签的首字符\n删除
    Z(".z-text-preline:not(pre),.z-text-prewrap:not(pre)").each(function(elem)
    {
        var $elem = Z(elem);
        var html = $elem.html();
        if (Z.V.isEmpty(html))
            return;
            
        if (html.charAt(0) == '\n'){
            $elem.html(html.substring(1));
        }
    });
}

Z.onload(Z.preRemoveBR);

//END
})(zhiqim);